# ifndef __Datum_H_
# define __Datum_H_

struct CEllipsoid;
class CTransformationBase;

struct CDatum {
	const char * strName;
	const char * strOziID;
	const CEllipsoid * pEllipsoid;
	float fDX;
	float fDY;
	float fDZ;
	float fWX;
	float fWY;
	float fWZ;
	float fMS;

	mutable CTransformationBase * pToWGS84;
	CTransformationBase * ToWGS84 () const;
};

extern CDatum g_Datums [];
extern const size_t c_cDatums;

bool FindOziDatumToWGS84 (const char * _strOziID, const CTransformationBase * & _pTransformation);

/////////////////////////////////////////////////////

# include "Transform.h"

class CMolodenskyTransformation : public CTransformationBase {
  public:
	CMolodenskyTransformation (
		const CEllipsoid & _SourceEllipsoid, const CEllipsoid & _DestEllipsoid,
		float _fDX, float _fDY, float _fDZ, // in meters
		float _fElevation = 0
	);
	virtual void ApplyTo (point_t & _point) const;

  protected:
	// The linear shifts, in meters.
	const float dx, dy, dz;

	// The average and difference of semin-major axes.
	const float a, da;
	// The average and difference of eccentricities.
	const float e2, de2;

	const float fElevation;
};

class CHelmertTransformation : public CMolodenskyTransformation {
  public:
	CHelmertTransformation (
		const CEllipsoid & _SourceEllipsoid, const CEllipsoid & _DestEllipsoid,
		float _fDX, float _fDY, float _fDZ, // in meters
		float _fWX, float _fWY, float _fWZ, // in arc seconds
		float _fMS,
		float _fElevation = 0
	);
	virtual void ApplyTo (point_t & _point) const;

  protected:
	// The angles between axis, in arc seconds.
	const float wx, wy, wz;
	// The scales difference.
	const float ms;
};

# endif // __Datum_H_
